#include "thttpclient.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QDateTime>
#include <QComboBox>
#include <json/json.h>
#include <hv/requests.h>
#include <QFileDialog>
#include <QDebug>
THttpClient::THttpClient(QWidget* parent)
    : QMainWindow(parent)
    , m_pUrlLabel(new QLabel(this))
    , m_pUrlLineEdit(new QLineEdit(this))
    , m_pTextEdit(new QTextEdit(this))
    , m_pSendButton(new QPushButton(this))
    , m_pMethod(new QComboBox(this))
    , m_pSelectImgButton(new QPushButton(this))
    , m_pSendImgButton(new QPushButton(this))
{
    resize(500, 500);
    initUI();
    initConnect();
}

void THttpClient::initConnect()
{
    connect(m_pSendButton, &QPushButton::released, this, &THttpClient::onSendJsonButtonReleased);
    connect(m_pSelectImgButton, &QPushButton::released, this, &THttpClient::onSelectImgButtonReleased);
    connect(m_pSendImgButton, &QPushButton::released, this, &THttpClient::onSendImgButtonReleased);
}

void THttpClient::onSendJsonButtonReleased()
{
    QString msg = m_pTextEdit->toPlainText();
    //构建json字符串
    Json::Value root;
    root["content"] = msg.toStdString();
    root["cmd"] = m_pMethod->currentText().toStdString();
    //root["time"] = QDateTime::currentDateTime().toString("hh:mm:ss").toStdString();
    Json::StreamWriterBuilder writer;
    std::string outputString = Json::writeString(writer, root);

    requests::Request req(new HttpRequest);
    req->SetMethod(m_pMethod->currentText().toStdString().c_str());
    req->SetUrl(m_pUrlLineEdit->text().toStdString().c_str());
    req->SetContentType("application/json");
    req->SetBody(outputString);
    requests::async(req, [this](const requests::Response& resp) {
        if (resp == nullptr) {
            std::cout << "request failed!" << std::endl;
        }
        else {
            std::cout << "received http response:\n" << resp->Dump(true, true) << std::endl;
        }
    });
}

void THttpClient::onSendImgButtonReleased()
{
    if (!m_pSelectImgButton->icon().isNull() && m_pMethod->currentText().toStdString() == "POST") {
        std::cout << "image is exist and POST" << std::endl;
        PictureType type = checkPictureType(selectedImagePath);
        requests::Request req(new HttpRequest);
        req->SetMethod(m_pMethod->currentText().toStdString().c_str());
        req->SetUrl(m_pUrlLineEdit->text().toStdString().c_str());
        req->SetContentType(APPLICATION_JSON);
        Json::Value root;

        /*switch (type) {
        case PictureType::ptJPG: root["image-type"] = "IMAGE_JPEG"; break;
        case PictureType::ptPNG: root["image-type"] = "IMAGE_PNG";  break;
        }*/

        root["image"] = imageToString(selectedImagePath);
        root["cmd"] = m_pMethod->currentText().toStdString();
        root["image-name"] = selectedImageName.toStdString();
        Json::StreamWriterBuilder writer;
        std::string outputString = Json::writeString(writer, root);
        req->SetBody(outputString);
        requests::async(req, [this](const requests::Response& resp) {
            if (resp == nullptr) {
                std::cout << "request failed!" << std::endl;
            }
            else {
                std::cout << "received http response:\n" << resp->Dump(true, true) << std::endl;
            }
        });
    }
    else
        std::cout << "image is not exist" << std::endl;   //只有POST能够向服务器发送图片，选择POST时能够传输图片和json
}

void THttpClient::onSelectImgButtonReleased()
{
    QString fileName = QFileDialog::getOpenFileName(this, "select iamge", "", "Images (*.png *.gif *.jpg *.bmp *.ico)");
    if (!fileName.isEmpty())
    {
        selectedImagePath = fileName;
        selectedImageName = QFileInfo(fileName).fileName();
        QPixmap pixmap(fileName);
        if (!pixmap.isNull())
        {
            QIcon icon(pixmap);
            m_pSelectImgButton->setIcon(icon);
            m_pSelectImgButton->setIconSize(m_pSelectImgButton->size());
        }
        else
            m_pSelectImgButton->setText("failed to load iamge");
    }
}

int THttpClient::cmdToInt(httpCmd command)
{
    return static_cast<int>(command);
}

void THttpClient::initUI()
{
    m_pUrlLabel->resize(50, 20);
    m_pUrlLabel->move(130, 20);
    m_pUrlLabel->setText("url:");

    m_pUrlLineEdit->resize(300, 20);
    m_pUrlLineEdit->move(185, 20);
    m_pUrlLineEdit->setText("http://172.16.191.79:9999/echo");

    m_pTextEdit->resize(400, 200);
    m_pTextEdit->move(10, 80);
    m_pTextEdit->append("测试");

    m_pSendButton->resize(40, 30);
    m_pSendButton->move(420, 150);
    m_pSendButton->setText("Send");

    m_pMethod->resize(60, 20);
    m_pMethod->move(20, 20);
    m_pMethod->addItems({ "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD" });
    m_pMethod->setCurrentText("POST");

    m_pSelectImgButton->resize(100, 100);
    m_pSelectImgButton->move(100, 300);
    //m_pSelectImgButton->setText("点击选择图片");

    m_pSendImgButton->move(300, 350);
    m_pSendImgButton->resize(50, 30);
    m_pSendImgButton->setText("Upload");
}

THttpClient::~THttpClient()
{}

PictureType THttpClient::checkPictureType(const QString& fileName) {//获取图片类型
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return PictureType::ptOther;
    }

    QByteArray header = file.read(8); // 读取前8个字节作为文件头
    file.close();

    if (header.startsWith("\x89PNG\r\n\x1a\n")) {
        return PictureType::ptPNG;
    }
    else if (header.size() >= 2 && header.at(0) == 0xFF && header.at(1) == 0xD8) {
        return PictureType::ptJPG;
    }
    else if (header.size() >= 2 && header.at(0) == 'B' && header.at(1) == 'M') {
        return PictureType::ptBMP;
    }
    else if (header.size() >= 3 && header.at(0) == 'G' && header.at(1) == 'I' && header.at(2) == 'F') {
        return PictureType::ptGIF;
    }
    else {
        return PictureType::ptOther;
    }
}

std::string THttpClient::imageToString(const QString& filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "Failed to open file:" << filename;
        return std::string();
    }
    QByteArray fileData = file.readAll();
    file.close();

    QByteArray base64Data = fileData.toBase64();
    QString base64String = QString::fromUtf8(base64Data);

    return base64String.toStdString();
}